﻿Imports System.Net
Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports System.ServiceModel.Dispatcher

Public Class CookieManagerMessageInspector
    Implements IClientMessageInspector
    Private Shared m_instance As CookieManagerMessageInspector
    Private sharedCookie As String

    ''' <summary>
    ''' Initializes a new instance of the <see cref="ClientIdentityMessageInspector"/> class.
    ''' </summary>
    Private Sub New()
    End Sub

    ''' <summary>
    ''' Gets the singleton <see cref="ClientIdentityMessageInspector" /> instance.
    ''' </summary>
    Public Shared ReadOnly Property Instance() As CookieManagerMessageInspector
        Get
            If m_instance Is Nothing Then
                m_instance = New CookieManagerMessageInspector()
            End If

            Return m_instance
        End Get
    End Property

    ''' <summary>
    ''' Inspects a message after a reply message is received but prior to passing it back to the client application.
    ''' </summary>
    ''' <param name="reply">The message to be transformed into types and handed back to the client application.</param>
    ''' <param name="correlationState">Correlation state data.</param>
    Public Sub AfterReceiveReply(ByRef reply As Message, correlationState As Object) Implements IClientMessageInspector.AfterReceiveReply

        Dim httpResponse As HttpResponseMessageProperty = TryCast(reply.Properties(HttpResponseMessageProperty.Name), HttpResponseMessageProperty)

        If httpResponse IsNot Nothing Then
            Dim cookie As String = httpResponse.Headers(HttpResponseHeader.SetCookie)

            If Not String.IsNullOrEmpty(cookie) Then
                Me.sharedCookie = cookie
            End If
        End If
    End Sub

    ''' <summary>
    ''' Inspects a message before a request message is sent to a service.
    ''' </summary>
    ''' <param name="request">The message to be sent to the service.</param>
    ''' <param name="channel">The client object channel.</param>
    ''' <returns>
    ''' <strong>Null</strong> since no message correlation is used.
    ''' </returns>
    Public Function BeforeSendRequest(ByRef request As Message, channel As IClientChannel) As Object Implements IClientMessageInspector.BeforeSendRequest
        Dim httpRequest As HttpRequestMessageProperty

        ' The HTTP request object is made available in the outgoing message only when
        ' the Visual Studio Debugger is attacched to the running process
        If Not request.Properties.ContainsKey(HttpRequestMessageProperty.Name) Then
            request.Properties.Add(HttpRequestMessageProperty.Name, New HttpRequestMessageProperty())
        End If

        httpRequest = DirectCast(request.Properties(HttpRequestMessageProperty.Name), HttpRequestMessageProperty)
        httpRequest.Headers.Add(HttpRequestHeader.Cookie, Me.sharedCookie)

        Return Nothing
    End Function
End Class
